package com.fingard.dsp.bank.directbank.zjtlcb02;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.AESCipher;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.MD5Util;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;

/**
 * Created by F on 2018/12/12.
 */
public class ZJTLCB02BatPayRec extends ZJTLCB02Base implements IBatPayRec {

    private static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    private static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=?;";

    /**
     * 批量代付提交
     *
     * @param p_req1988
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        //返回ATS的对象
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        Connection conn= FGBiz.getLocalDbConn();
        try{
            String seqNo=getQryTransID();
            //报文头
            JSONObject jsonHead = new JSONObject();
            jsonHead.put("txSno",p_req1988.reqBatchNO);// 交易流水号
            jsonHead.put("mrchSno",p_req1988.reqBatchNO);// 商户业务编号
            jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
            jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
            jsonHead.put("productId",""); // 产品ID
            //报文体
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("sourceType","J01");//	渠道类型
            jsonBody.put("branchId",getBankConfig().getValueAsString("branchId"));//	发送方机构号
            jsonBody.put("userId",getBankConfig().getValueAsString("userId"));//	服务请求者身份
            jsonBody.put("orgSysId",getBankConfig().getValueAsString("orgSysId"));//	原始发起方系统ID
            jsonBody.put("corpCode",getBankConfig().getValueAsString("corpCode"));//	法人类型代码
            jsonBody.put("pyrCstmrAcctNo",p_req1988.ownAct);//	付款人客户账号
            jsonBody.put("feeAcctNm",p_req1988.ownActName);//付费账号名称
            jsonBody.put("payerOpenBankCode	",p_req1988.ownBankCode);//付款人开户行行号
            jsonBody.put("ccy",convertCurToBank(p_req1988.ownCur));//币种
            jsonBody.put("abstract",p_req1988.useType);//	摘要
            jsonBody.put("payDate", DateHelper.convertD10toD8(p_req1988.payDate).substring(0,6));//付款日期
            jsonBody.put("clientNo",bankFront.org);//	客户号
            String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>付款账号</k><v>"+p_req1988.ownAct+"</v></M>" +
                    "<M><k>代发工资年月</k><v>"+DateHelper.convertD10toD8(p_req1988.payDate).substring(0,6)+"</v></M><M>" +
                    "<k>交易总金额</k><v>"+p_req1988.totalAmt+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
            jsonBody.put("signCert",ukeyData(data).trim());//	签名证书
            jsonBody.put("tranAmt",p_req1988.totalAmt);//	交易金额
            //第三方交易流水
            String bankSeqId=getThirdSeqNo();
            //记录ats支付流水号对应的银行支付流水号，供查询状态接口使用
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1988.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1988.reqBatchNO, bankSeqId});
            jsonBody.put("thirdSeqNo",bankSeqId);//	第三方流水号
            int tmpCount = 0;
            JSONArray array=new JSONArray();
            while(p_req1988.readRecord()){
                tmpCount++;
                String askNumber=p_req1988.readedDetail.askNumber;//批内流水号
                String abstractATS=p_req1988.readedDetail.abstractATS;//对账码
                JSONObject object=new JSONObject();
                object.put("srlNo",tmpCount);//	序号
                object.put("acctNo",p_req1988.readedDetail.recAct);//	账号
                object.put("acctName",p_req1988.readedDetail.recName);//	账户名称
                object.put("openBankCode","");//	开户行行号
                object.put("amnt",p_req1988.readedDetail.payAmount);//	金额
                object.put("ccy",convertCurToBank(p_req1988.readedDetail.recCur));//	币种
                object.put("purpose",askNumber);//	用途
                array.add(object);
            }
            jsonBody.put("payeeInfoArray",array);//收款人信息数组
            //报文内容
            JSONObject jsonReqData = new JSONObject();
            jsonReqData.put("head", jsonHead);
            jsonReqData.put("body", jsonBody);
            //拼接请求json串:data
            JSONObject jsonObject = new JSONObject();
            ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
            tlcb02Header.seqNO = seqNo;
            //验证开发者
            String appAccessToken=checkDeveloper(seqNo);
            tlcb02Header.appAccessToken = appAccessToken;
            //MD5加密签名串
            WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
            String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
            tlcb02Header.sign = sign;
            JsonHeader(jsonObject, tlcb02Header);
            jsonObject.put("reqData", jsonReqData);
            WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
            //AES256加密
            String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
            jsonObject.put("reqData", aesData);
            //发送请求报文
            String[] tmpStrRet = sendToBank(jsonObject.toString(),"batchSalaryReleaseBCDC");
            if(tmpStrRet[0].length() == 0){
                JSONObject jsonArray = JSONObject.fromObject(tmpStrRet[1].replaceAll(" ",""));
                //AES256解密
                String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                jsonArray.put("rspData",rspData);
                WriteBankLogLn("银行返回已解密的报文："+jsonArray.toString());
                if(!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode")!=null){
                    if(isActiveRetCode(jsonArray.get("errorCode").toString())){
                        JSONObject jsonRspData=JSONObject.fromObject(rspData);
                        JSONObject jsonBodys=(JSONObject)jsonRspData.get("body");
                        if(!"".equals(jsonBodys) && jsonBodys!=null){
                            retAts.respCode = "0";
                            retAts.respInfo = "";
                            retAts.reqSeqID = p_req1988.reqBatchNO;
                            retAts.transState = jsonBodys.get("orderStatus")!=null?jsonBodys.get("orderStatus").toString():"3";//未返回字段状态为3处理中
                            retAts.payInfoCode = retAts.transState;
                        }else {
                            retAts.respCode = "0";
                            retAts.respInfo = "返回rspData或者body内容为空";
                            retAts.reqSeqID = p_req1988.reqBatchNO;
                            retAts.transState = PaymentState.FAIL_Batch;
                            retAts.payInfoCode = tmpStrRet[0];
                        }
                    }else {
                        retAts.respCode = "-1";
                        retAts.respInfo = jsonArray.get("errorMsg").toString();
                    }
                }else {
                    retAts.respCode = "0";
                    retAts.respInfo = "响应码未返回";
                    retAts.reqSeqID = p_req1988.reqBatchNO;
                    retAts.transState = PaymentState.FAIL_Batch;
                    retAts.payInfoCode = tmpStrRet[0];
                }
            }else if(tmpStrRet[0].equals(ConnState.FAIL)){
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = tmpStrRet[0];
            }
            else{
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        }catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            e.printStackTrace();
        }finally {
            conn.close();
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1988.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        // 返回ATS的对象
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn=FGBiz.getLocalDbConn();
        try {
            String seqNo=getQryTransID();
            //报文头
            JSONObject jsonHead = new JSONObject();
            jsonHead.put("txSno",p_req1998.reqHeader.transSeqID);// 交易流水号
            jsonHead.put("mrchSno",p_req1998.reqHeader.reqSeqID);// 商户业务编号
            jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
            jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
            jsonHead.put("productId",""); // 产品ID
            //报文体
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("sourceType","J01");//	渠道类型
            Map<String, Object> selMap=JDBCHelper.execQuerySingle(conn,SELECTSEQ,new Object[]{p_req1998.reqBatchNO});
            String seqNo2="";
            if(selMap.size()>0){
                seqNo2=selMap.get("BANKREQSEQID").toString();//第三方流水号
            }else {
                retAts.respCode = "-1";
                retAts.respInfo = "系统交易流水号关联映射异常，请检查";
                retAts.writeAfterDetail();
                return retAts;
            }
            jsonBody.put("branchId",getBankConfig().getValueAsString("branchId"));//	发送方机构号
            jsonBody.put("userId",getBankConfig().getValueAsString("userId"));//	服务请求者身份
            jsonBody.put("orgSysId",getBankConfig().getValueAsString("orgSysId"));//	原始发起方系统ID
            jsonBody.put("corpCode",getBankConfig().getValueAsString("corpCode"));//	法人类型代码
            jsonBody.put("pyrCstmrAcctNo",p_req1998.ownAct);//付款人客户账号
            jsonBody.put("feeAcctNm","");//付费账号名称
            jsonBody.put("seqNo",seqNo2);//流水号
            jsonBody.put("ccy",convertCurToBank(getBankConfig().getMapKeyByValue("curActMapping", p_req1998.ownAct)));//币种
            jsonBody.put("startDate","");//开始日期
            jsonBody.put("endDate","");//终止日期
            jsonBody.put("clientNo",bankFront.org);//	客户号
            String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>付款账号</k><v>"+p_req1998.ownAct+"</v></M><M><k>支付流水号</k><v>"+seqNo2+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
            jsonBody.put("signCert",ukeyData(data).trim());//	签名证书
            jsonBody.put("thirdSeqNo",seqNo2);//第三方流水号
            jsonBody.put("payeeInfoArray","");//收款人信息数组
            jsonBody.put("totalNum","");//本页记录总数
            jsonBody.put("currentNum","");//当前记录号
            //报文内容
            JSONObject jsonReqData = new JSONObject();
            jsonReqData.put("head", jsonHead);
            jsonReqData.put("body", jsonBody);
            //拼接请求json串:data
            JSONObject jsonObject = new JSONObject();
            ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
            tlcb02Header.seqNO = seqNo;
            //验证开发者
            String appAccessToken=checkDeveloper(seqNo);
            tlcb02Header.appAccessToken = appAccessToken;
            //MD5加密签名串
            WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
            String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
            tlcb02Header.sign = sign;
            JsonHeader(jsonObject, tlcb02Header);
            jsonObject.put("reqData", jsonReqData);
            WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
            //AES256加密
            String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
            jsonObject.put("reqData", aesData);
            //发送请求报文
            String[] bankResult = sendToBank(jsonObject.toString(),"agentSDTranQryBCDC");
            if (bankResult[0].length() == 0) {
                JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ",""));
                //AES256解密
                String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                jsonArray.put("rspData",rspData);
                WriteBankLogLn("银行返回已解密的报文："+jsonArray.toString());
                if(!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode")!=null){
                    if(isActiveRetCode(jsonArray.get("errorCode").toString())){
                        JSONObject jsonRspData=JSONObject.fromObject(rspData);
                        JSONObject jsonBodys=(JSONObject)jsonRspData.get("body");
                        if(!"".equals(jsonBodys) && jsonBodys!=null){
                            if(jsonBodys.get("payeeInfoArray")!=null && !"".equals(jsonBodys.get("payeeInfoArray").toString())){
                                String payeeInfoArray=jsonBodys.get("payeeInfoArray").toString();
                                JSONArray json = JSONArray.fromObject(payeeInfoArray);
                                if(json.size()>0){
                                    retAts.respCode = "0";
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.writeBeforeDetail();
                                    for(int i=0;i<json.size();i++){
                                        JSONObject object = json.getJSONObject(i);
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        tmpRetDetail.payAct = p_req1998.ownAct;
                                        tmpRetDetail.payName = "";
                                        tmpRetDetail.recName = object.get("acctName")!=null?object.get("acctName").toString():"";
                                        tmpRetDetail.recAct =object.get("acctNo")!=null?object.get("acctNo").toString():"";
                                        tmpRetDetail.payAmount = object.get("amnt")!=null?object.get("amnt").toString():"";
                                        tmpRetDetail.curType = object.get("ccy")!=null?convertCurToATS(object.get("ccy").toString())
                                                :convertCurToATS(getBankConfig().getMapKeyByValue("curActMapping", tmpRetDetail.recAct));
                                        tmpRetDetail.result = object.get("txnRsltCd")!=null?object.get("txnRsltCd").toString():"3";
                                        tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                        if(object.get("purpose")!=null){
                                            tmpRetDetail.postScript = object.get("purpose").toString();//批内流水号
                                            tmpRetDetail.usage =object.get("purpose").toString();
                                        }else {
                                            tmpRetDetail.postScript = "";//批内流水号
                                            tmpRetDetail.usage = "";
                                        }
                                        // tmpRetDetail.usage = strings[1];
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                }else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "返回payeeInfoArray内容为空";
                                }
                            }else {
                                retAts.respCode = "-1";
                                retAts.respInfo = "返回payeeInfoArray内容为空";
                            }
                        }else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "返回rspData或者body内容为空";
                        }
                    }else {
                        retAts.respCode = "-1";
                        retAts.respInfo = jsonArray.get("errorMsg").toString();
                    }
                }else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "响应码未返回";
                }
            }else {
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }finally {
            conn.close();
        }
        if ("-1".equals(retAts.respCode) && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1998.reqBatchNO;
        }
        if ("-1".equals(retAts.respCode)) {
            retAts.writeBeforeDetail();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
